Ant Design v5

记录项目开发过程中遇到的一些问题(antd 5.x)

官网镜像地址

ant-design各版本国内镜像:https://github.com/ant-design/ant-design/issues/25661

Ant Design 5.x:

Form

根据某个表单项的值渲染其他表单项

shouldUpdate

shouldUpdate: boolean | (prevValue, curValue) => boolean

1
2
3
4
5
6
7
8
9
10
<Form.Item noStyle shouldUpdate>
{({getFieldValue}) => {
// 通过getFieldValue获取所需的字段值
return (
<Form.Item name="other">
<Input/>
</Form.Item>
)
}}
</Form.Item>

一个表单项中有多个控件

复杂一点的控件

提交失败时自动滚动到指定字段

自定义表单控件 scrollToFirstError 和 scrollToField 失效?

  1. scrollToFirstError

提交失败自动滚动到第一个错误字段。

注意:必须使用表单submit提交才会触发。

  1. scrollToField

如果不使用表单submit提交,使用scrollToField滚动到对应字段位置:

1
scrollToField(name: NamePath, options: ScrollOptions)

ScrollOptions

1
2
3
4
5
6
7
8
9
10
const submit = async () => {
try {
const values = await form.validateFields();
} catch (errorInfo) {
// 滚动到第一个错误字段
form.scrollToField(errorInfo.errorFields[0].name, {
block: 'center',
})
}
}

嵌套结构校验

校验嵌套数据结构中的某几个项:

1
2
3
4
5
6
<FormItem name={['app', 'name' ]}>
<Input />
</FormItem>
<FormItem name={['app', 'desc' ]}>
<Input />
</FormItem>
1
2
// 只校验app.name
form.validateFields([['app', 'name' ]])

Form.List的局部校验

https://juejin.cn/post/6844904176770613261

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 单行验证, index代表的是第几行数据
form.validateFields([
['users', index, 'firstName'],
['users', index, 'lastName']
]).then(values => {
console.log(values.users[index].firstName, values.users[index].lastName)
});

// 整个users验证需要把每行的field name传进去,暂未找到别的解决方案
form.validateFields([
['users', 0, 'firstName'],
['users', 0, 'lastName'],
['users', 1, 'firstName'],
['users', 1, 'lastName']
])

关闭Modal销毁form中的数据

4.5.0之后,可以给Form加上preserve={false}属性来清除跟随Modal 销毁的字段数据:https://codesandbox.io/s/mystifying-sound-lkin8

Instance created by useForm is not connect to any Form element. Forget to pass form prop?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const formRef = useRef(null)

useEffect(() => {
if (formRef.current)
form.setFieldsValue({
// ...
})
}, [])

return (
<Form
ref={formRef}
form={form}
initialValues={...}
onFinish={...}
>
}

Select

如果发现下拉菜单跟随页面滚动,或者需要在其他弹层中触发 Select,请尝试使用getPopupContainer={triggerNode => triggerNode.parentElement}将下拉弹层渲染节点固定在触发器的父元素中。

自定义回填内容

optionLabelProp="name"

1
2
3
<Select optionLabelProp="name">
<Option key="..." name={opt.name} value="..."} />
</Select>

自定义搜索筛选filterOption

利用option.keyoption.title

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<Select showSearch filterOption={(input, option) => {
const inputSearch = input.toLowerCase();
return option.key.toLowerCase().indexOf(inputSearch) >= 0 || option.title.toLowerCase().indexOf(inputSearch) >= 0;
}}>
{countries.map((country) => {
const { abbreviation, emoji, englishName } = country;
const value = valueWidthName ? `${abbreviation},${englishName}` : abbreviation;
return (
<Option key={value} title={englishName} value={value}>
<div className={classNames(style.option, optionClassName)}>
<Twemoji className={classNames(style.emoji, emojiClassName)}>{emoji}</Twemoji>
<span className={style.name}>{englishName}</span>
</div>
</Option>
);
})}
</Select>

滚动加载

onPopupScroll: 下拉列表滚动时的回调

1
2
3
4
5
6
7
8
9
const handlePopupScroll = (e) => {
const {target} = e
if (target.scrollTop + target.offsetHeight === target.scrollHeight) {
if (loading) {
return
}
// ...
}
}

Tree

虚拟滚动

默认virtual: true开启虚拟滚动,通过添加height属性激活。如果需要支持横向滚动,应该关闭虚拟滚动,因为虚拟滚动不会渲染所有节点,无法自动拓转横向宽度(虚拟滚动的限制)。

onSelect获取key

1
2
3
4
const onSelect = (selectedKeys, e) => {
const key = e.node.key
// ...
}

Table

表头分组(嵌套表头)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
title: '表头分组',
dataIndex: 'group',
align: 'center',
children: [
{
title: '分组1',
dataIndex: ['group', 'children1'],
align: 'center'
},
{
title: '分组2',
dataIndex: ['group', 'children2'],
align: 'center'
}
]
}

rowSelection.renderCell

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
renderCell: (_value, _record, _index, originNode) => {
// return ...
},
```

### Drawer

#### 监听滚动事件

Drawer滚动事件在`ant-drawer-body`节点上,可以通过修改css,转移滚动对象,使`ant-drawer-body`不滚动。

### Modal

#### 网页全屏下Modal不显示问题

使用`getContainer`:

```jsx
<Modal
getContainer={() => dom} // <----
>
// ...
</Modal>

Table